
#pragma once

#include <string>
#include <map>
#include <vector>
#include <functional>
#include <memory>
#include "Parameter.h"
#include "Application.h"

#define registerApp(name) Factory::instance().reg<name>(#name)

using BuilderType = std::function<std::shared_ptr<Application>(const Parameter&)>;

template<typename T>
std::shared_ptr<Application> build(const Parameter& params)
{
	return std::make_shared<T>(params);
}

struct Factory
{

	static Factory& instance() { return _instance; }
	static Factory _instance;

	std::shared_ptr<Application> createApp(const string& app_name, int argc, char** argv)
	{
		Parameter p;
		return (_app_builder[app_name])(p);
	}

	template<typename T>
	void reg(const std::string& name)
	{
		_app_builder[name] = build<T>;
	}
protected:
	std::map<std::string, BuilderType> _app_builder;

};

Factory Factory::_instance = Factory{};

